﻿#region Copyright (c) 2000-2008 Developer Express Inc.
/*
{*******************************************************************}
{                                                                   }
{       Developer Express .NET Component Library                    }
{       AgDataGrid                                 }
{                                                                   }
{       Copyright (c) 2000-2008 Developer Express Inc.              }
{       ALL RIGHTS RESERVED                                         }
{                                                                   }
{   The entire contents of this file is protected by U.S. and       }
{   International Copyright Laws. Unauthorized reproduction,        }
{   reverse-engineering, and distribution of all or any portion of  }
{   the code contained in this file is strictly prohibited and may  }
{   result in severe civil and criminal penalties and will be       }
{   prosecuted to the maximum extent possible under the law.        }
{                                                                   }
{   RESTRICTIONS                                                    }
{                                                                   }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES           }
{   ARE CONFIDENTIAL AND PROPRIETARY TRADE                          }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS   }
{   LICENSED TO DISTRIBUTE THE PRODUCT AND ALL ACCOMPANYING .NET    }
{   CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY.                 }
{                                                                   }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED      }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE        }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE       }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT  }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                      }
{                                                                   }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON       }
{   ADDITIONAL RESTRICTIONS.                                        }
{                                                                   }
{*******************************************************************}
*/
#endregion Copyright (c) 2000-2008 Developer Express Inc.

using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace DevExpress.AgMenu.Utils {
	public enum Side { Left, Top, Right, Bottom };
	public static class SideExtentions {
		public static HorizontalAlignment GetHorizontalAlignment(this Side side) {
			if(side.GetOrientation() == Orientation.Vertical)
				return side.IsStart() ? HorizontalAlignment.Left : HorizontalAlignment.Right;
			else
				return HorizontalAlignment.Stretch;
		}
		public static VerticalAlignment GetVerticalAlignment(this Side side) {
			if(side.GetOrientation() == Orientation.Horizontal)
				return side.IsStart() ? VerticalAlignment.Top : VerticalAlignment.Bottom;
			else
				return VerticalAlignment.Stretch;
		}
		public static Orientation GetOrientation(this Side side) {
			return side == Side.Left || side == Side.Right ? Orientation.Vertical : Orientation.Horizontal;
		}
		public static bool IsStart(this Side side) {
			return side == Side.Left || side == Side.Top;
		}
		public static bool IsEnd(this Side side) {
			return side == Side.Right || side == Side.Bottom;
		}
	}
	public delegate void ValueChangedEventHandler<T>(object sender, ValueChangedEventArgs<T> e);
	public class ValueChangedEventArgs<T> : EventArgs {
		public ValueChangedEventArgs(T previousValue, T value) {
			PreviousValue = previousValue;
			Value = value;
		}
		public T PreviousValue { get; private set; }
		public T Value { get; private set; }
	}
	public class FrameworkElements : ObservableCollection<FrameworkElement> { }
	public abstract class ElementPool {
		private Panel _Container;
		private FrameworkElements _Items;
		private FrameworkElements _UsedItems;
		public ElementPool(Panel container) {
			_Container = container;
			_Items = new FrameworkElements();
			_UsedItems = new FrameworkElements();
		}
		public FrameworkElement Add() {
			var result = GetFirstUnusedItem();
			if(result == null) {
				result = CreateItem();
				Items.Add(result);
				Container.Children.Add(result);
			}
			MarkItemAsUsed(result);
			return result;
		}
		public void DeleteUnusedItems() {
			for(int i = Items.Count - 1; i >= 0; i--)
				if(!IsItemUsed(Items[i])) {
					Container.Children.Remove(Items[i]);
					Items.RemoveAt(i);
				}
		}
		public int IndexOf(FrameworkElement item) {
			return Items.IndexOf(item);
		}
		public abstract bool IsItem(UIElement element);
		public void MarkItemsAsUnused() {
			foreach(FrameworkElement item in Items)
				MarkItemAsUnused(item);
		}
		public FrameworkElement this[int index] { get { return Items[index]; } }
		public Panel Container { get { return _Container; } }
		public int Count { get { return Items.Count; } }
		protected abstract FrameworkElement CreateItem();
		protected FrameworkElement GetFirstUnusedItem() {
			foreach(FrameworkElement item in Items)
				if(!IsItemUsed(item))
					return item;
			return null;
		}
		protected bool IsItemUsed(FrameworkElement item) {
			return _UsedItems.Contains(item);
		}
		protected void MarkItemAsUnused(FrameworkElement item) {
			_UsedItems.Remove(item);
		}
		protected void MarkItemAsUsed(FrameworkElement item) {
			_UsedItems.Add(item);
		}
		protected FrameworkElements Items { get { return _Items; } }
	}
	public class VisualTreeUtils {
		public static T FindRoot<T>(FrameworkElement elem) where T : FrameworkElement {
			FrameworkElement parent = elem.GetParent();
			T typedParent = parent as T;
			while(parent != null && typedParent == null) {
				parent = parent.GetParent();
				typedParent = parent as T;
			}
			return typedParent;
		}
	}
}
